package com.henu.acmrating.crawler;

import com.henu.acmrating.pojo.UserOj;
import com.henu.acmrating.service.ProblemService;
import com.henu.acmrating.service.UserOjService;
import com.henu.acmrating.webmagic.SeleniumDownloader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

@Component
public class LuoguProcessor implements PageProcessor {

    private static final String OJ_NAME = "Luogu";
    private static final String BASE_URL = "https://www.luogu.com.cn/user/";

    @Resource
    UserOjService userOjService;


    public static LuoguProcessor luoguProcessor;

    @PostConstruct
    public void init() {
        luoguProcessor = this;
    }

    private static Integer string2Integer(String s) {
        if(s.contains("k")) {
            return (int) (Double.parseDouble(s.substring(0, s.length()-1)) * 1000);
        }
        return Integer.parseInt(s);
    }

//    public static void main(String[] args) {
////        ;
//        System.out.println(string2Integer("1.122k"));
//        System.out.println(string2Integer("456"));
//    }


    @Override
    public void process(Page page) {
        Html html = page.getHtml();
        List<Selectable> nodes = html.xpath("//span[@class='value']").nodes();
        if(nodes.size() == 0) return ;
        int solved = 0, submissions = 0;
        if(nodes.size() >= 4) {
            submissions = string2Integer(nodes.get(2).xpath("//span/allText()").toString());
            solved = string2Integer(nodes.get(3).xpath("//span/allText()").toString());
        }
        String account = page.getUrl().toString().split("/")[4];
        UserOj userOj = luoguProcessor.userOjService.selectByAccountAndOjName(account, OJ_NAME);
        // 之前一样不更新
        if(userOj.getSolved().equals(solved) && userOj.getSubmissions().equals(submissions)) return ;
        userOj.setSolved(solved);
        userOj.setSubmissions(submissions);

        luoguProcessor.userOjService.updateByPrimaryKey(userOj);
    }


    private Site site = Site.me()
            .setTimeOut(15 * 1000)  // 设置超时时间
            .setRetrySleepTime(3000)// 设置重试的间隔时间
            .setRetryTimes(3);      // 设置重试次数


    @Override
    public Site getSite() { return site; }

    @Value("${prop.driver-path}")
    private  String driverPath;


    @Scheduled(cron = "0 30 3 ? * * ")
    public void start() {
        Spider.create(new LuoguProcessor())
                .addUrl(BaseProcessor.getUrls(userOjService, OJ_NAME, BASE_URL))
                .setDownloader(new SeleniumDownloader(driverPath))
                .thread(1)
                .start();
    }

    public static void run_all() {
        Spider.create(new LuoguProcessor())
                .addUrl(BaseProcessor.getUrls(luoguProcessor.userOjService, OJ_NAME, BASE_URL))
                .setDownloader(new SeleniumDownloader(luoguProcessor.driverPath))
                .thread(1)
                .start();
    }


    public static void run(String id) {
        Spider.create(new LuoguProcessor())
                .addUrl(BASE_URL + id)
                .setDownloader(new SeleniumDownloader(luoguProcessor.driverPath))
                .thread(1)
                .start();
    }
}
